"""
API路由模块
"""
from datetime import datetime
from flask import Blueprint, request, jsonify
from loguru import logger
import pandas as pd
from sqlalchemy import text

from data_fetcher.daily_data_fetcher import fetch_daily_data_by_date_range
from data_fetcher.realtime_data_fetcher import fetch_realtime_data
from data_fetcher.stock_info_fetcher import update_stock_basic_info
from database.db_engine import SessionLocal
from models.stock_models import StockDailyData, StockRealtimeData, StockBasicInfo

# 创建蓝图
api = Blueprint('api', __name__)

@api.route('/stock/daily', methods=['POST'])
def get_stock_daily_data():
    """
    获取股票日线数据并保存到数据库
    
    请求参数:
    {
        "start_date": "YYYYMMDD",  # 必填，开始日期
        "end_date": "YYYYMMDD",    # 必填，结束日期
        "stock_codes": ["000001"]  # 可选，股票代码列表
    }
    """
    try:
        # 获取请求参数
        data = request.get_json()
        
        # 验证必填参数
        if not data or 'start_date' not in data or 'end_date' not in data:
            return jsonify({
                'code': 400,
                'message': '缺少必填参数：start_date 或 end_date',
                'data': None
            }), 400
            
        start_date = data['start_date']
        end_date = data['end_date']
        stock_codes = data.get('stock_codes', None)  # 可选参数
        
        # 验证日期格式
        try:
            start_date_obj = datetime.strptime(start_date, '%Y%m%d')
            end_date_obj = datetime.strptime(end_date, '%Y%m%d')
            
            # 只验证结束日期不能超过当前日期
            current_date = datetime.now()
            if end_date_obj > current_date:
                return jsonify({
                    'code': 400,
                    'message': '结束日期不能超过当前日期',
                    'data': None
                }), 400
        except ValueError:
            return jsonify({
                'code': 400,
                'message': '日期格式错误，应为YYYYMMDD',
                'data': None
            }), 400
            
        # 验证日期范围
        if start_date > end_date:
            return jsonify({
                'code': 400,
                'message': '开始日期不能大于结束日期',
                'data': None
            }), 400
            
        # 验证股票代码格式（如果提供）
        if stock_codes:
            if not isinstance(stock_codes, list):
                return jsonify({
                    'code': 400,
                    'message': 'stock_codes 必须是列表格式',
                    'data': None
                }), 400
            
            # 验证每个股票代码的格式
            for code in stock_codes:
                if not isinstance(code, str) or len(code) != 6 or not code.isdigit():
                    return jsonify({
                        'code': 400,
                        'message': f'无效的股票代码格式：{code}',
                        'data': None
                    }), 400
        
        # 获取数据
        logger.info(f"开始获取股票数据，日期范围：{start_date}-{end_date}，股票代码：{stock_codes or '全部'}")
        success, result = fetch_daily_data_by_date_range(start_date, end_date, stock_codes)
        
        if not success:
            return jsonify({
                'code': 500,
                'message': '获取股票数据失败',
                'data': None
            }), 500
            
        if result['data'].empty:
            return jsonify({
                'code': 404,
                'message': '未找到符合条件的数据',
                'request_params': {
                    'start_date': start_date,
                    'end_date': end_date,
                    'stock_codes': stock_codes
                },
                'data': None
            }), 404
        
        # 转换为字典列表
        data_list = result['data'].to_dict('records')
        
        return jsonify({
            'code': 200,
            'message': 'success',
            'data': {
                'total': len(data_list),
                'items': data_list,
                'db_stats': result['db_stats']
            }
        })
        
    except Exception as e:
        logger.error(f"获取股票日线数据失败: {e}")
        return jsonify({
            'code': 500,
            'message': f'服务器内部错误: {str(e)}',
            'data': None
        }), 500

@api.route('/stock/realtime', methods=['POST'])
def get_stock_realtime_data():
    """
    获取股票实时数据
    
    请求参数:
    {
        "stock_codes": ["600000"]  # 必填，股票代码列表
    }
    """
    try:
        # 获取请求参数
        data = request.get_json()
        
        # 验证必填参数
        if not data or 'stock_codes' not in data:
            return jsonify({
                'code': 400,
                'message': '缺少必填参数：stock_codes',
                'data': None
            }), 400
            
        stock_codes = data['stock_codes']
        
        # 验证股票代码列表格式
        if not isinstance(stock_codes, list):
            return jsonify({
                'code': 400,
                'message': 'stock_codes 必须是列表格式',
                'data': None
            }), 400
        
        # 验证每个股票代码的格式
        for code in stock_codes:
            if not isinstance(code, str) or len(code) != 6 or not code.isdigit():
                return jsonify({
                    'code': 400,
                    'message': f'无效的股票代码格式：{code}',
                    'data': None
                }), 400
        
        # 获取实时数据
        logger.info(f"开始获取股票实时数据，股票代码：{stock_codes}")
        df = fetch_realtime_data()
        
        if df.empty:
            return jsonify({
                'code': 404,
                'message': '未获取到实时数据',
                'request_params': {
                    'stock_codes': stock_codes
                },
                'data': None
            }), 404
        
        # 过滤指定的股票代码
        filtered_df = df[df['stock_code'].isin(stock_codes)]
        
        if filtered_df.empty:
            return jsonify({
                'code': 404,
                'message': '未找到指定股票的实时数据',
                'request_params': {
                    'stock_codes': stock_codes
                },
                'data': None
            }), 404
        
        # 只保留数据库模型中存在的列
        model_columns = StockRealtimeData.__table__.columns.keys()
        db_columns = [col for col in filtered_df.columns if col in model_columns and col != 'id']
        db_df = filtered_df[db_columns].copy()
        
        # 保存数据到数据库
        db = SessionLocal()
        try:
            records_inserted = 0
            
            for _, row in db_df.iterrows():
                # 将数据转换为字典，并处理nan值
                realtime_dict = row.where(pd.notnull(row), None).to_dict()
                
                # 创建新记录
                new_data = StockRealtimeData(**realtime_dict)
                db.add(new_data)
                records_inserted += 1
            
            # 提交事务
            db.commit()
            logger.info(f"实时数据保存成功：新增 {records_inserted} 条记录")
            
        except Exception as e:
            db.rollback()
            logger.error(f"保存实时数据到数据库失败: {e}")
            raise
        finally:
            db.close()
        
        # 转换为字典列表（返回所有列，包括非数据库列）
        data_list = filtered_df.to_dict('records')
        
        return jsonify({
            'code': 200,
            'message': 'success',
            'data': {
                'total': len(data_list),
                'items': data_list,
                'db_stats': {
                    'inserted': records_inserted
                }
            }
        })
        
    except Exception as e:
        logger.error(f"获取股票实时数据失败: {e}")
        return jsonify({
            'code': 500,
            'message': f'服务器内部错误: {str(e)}',
            'data': None
        }), 500

@api.route('/stock/basic', methods=['POST'])
def get_stock_basic_info():
    """
    获取股票基础信息
    
    请求参数:
    {
        "stock_codes": ["000001"]  # 可选，股票代码列表，为空时获取全量数据
    }
    """
    try:
        # 获取请求参数
        data = request.get_json() or {}
        stock_codes = data.get('stock_codes')
        
        # 验证股票代码格式（如果提供）
        if stock_codes is not None:
            if not isinstance(stock_codes, list):
                return jsonify({
                    'code': 400,
                    'message': 'stock_codes 必须是列表格式',
                    'data': None
                }), 400
            
            # 验证每个股票代码的格式
            for code in stock_codes:
                if not isinstance(code, str) or len(code) != 6 or not code.isdigit():
                    return jsonify({
                        'code': 400,
                        'message': f'无效的股票代码格式：{code}',
                        'data': None
                    }), 400
        
        # 调用更新接口获取数据
        logger.info(f"开始获取股票基础信息，股票代码：{stock_codes or '全部'}")
        success = update_stock_basic_info(stock_codes)
        
        if success:
            return jsonify({
                'code': 200,
                'message': '获取股票基础信息成功',
                'data': None
            })
        else:
            return jsonify({
                'code': 500,
                'message': '获取股票基础信息失败',
                'data': None
            }), 500
            
    except Exception as e:
        logger.error(f"获取股票基础信息失败: {e}")
        return jsonify({
            'code': 500,
            'message': f'服务器内部错误: {str(e)}',
            'data': None
        }), 500 